﻿#pragma warning disable 1591

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace TotalFreedomBST
{
    /// <summary>
    /// Main accordion section    
    /// </summary>
    public class AccordionSection : BstSection
    {
        private HtmlHelper _htmlHelper;

        public Accordion Accordion { get; set; }

        public AccordionSection(HtmlHelper htmlHelper, Accordion accordion, string id, object htmlAttributes)
            : base(htmlHelper.ViewContext, "</div>")
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            if (accordion != null)
                Accordion = accordion;
            else
                Accordion = new Accordion(id, attrs);

            _htmlHelper = htmlHelper;
        }

        public override string StartHtml()
        {
            return "<div " + BstHelperExtensions.ValuePlusAttribute("class", "accordion", Accordion.HtmlAttributes) + BstHelperExtensions.AttributeOrDefault(Accordion.HtmlAttributes, "id", Accordion.Id) + "\">";
        }

        public AccordionGroupSection AccordionGroup(AccordionGroup accordionGroup, string header, string id = null, object htmlAttributes = null)
        {
            return AccordionGroup(accordionGroup, new MvcHtmlString(HttpUtility.HtmlEncode(header)), id, htmlAttributes);
        }

        public AccordionGroupSection AccordionGroup(AccordionGroup accordionGroup, MvcHtmlString header, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            AccordionGroupSection accordionGroupSection = new AccordionGroupSection(this.Accordion, _htmlHelper.ViewContext, accordionGroup, AccordionGroupOptions.None, id, attrs);

            _htmlHelper.ViewContext.Writer.Write(accordionGroupSection.StartHtml(header));

            return accordionGroupSection;
        }

        public AccordionGroupSection AccordionGroup(string header, AccordionGroupOptions options = AccordionGroupOptions.None, string id = null, object htmlAttributes = null)
        {
            return AccordionGroup(new MvcHtmlString(HttpUtility.HtmlEncode(header)), options, id, htmlAttributes);
        }

        public AccordionGroupSection AccordionGroup(IHtmlString header, AccordionGroupOptions options = AccordionGroupOptions.None, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            AccordionGroupSection accordionGroupSection = new AccordionGroupSection(this.Accordion, _htmlHelper.ViewContext, null, options, id, attrs);

            _htmlHelper.ViewContext.Writer.Write(accordionGroupSection.StartHtml(header));

            return accordionGroupSection;
        }

        public MvcHtmlString AccordionGroupFromPartial(string header, string partialName, object model = null, ViewDataDictionary viewData = null, AccordionGroupOptions options = AccordionGroupOptions.None, string id = null)
        {
            return AccordionGroupFromPartial(new MvcHtmlString(HttpUtility.HtmlEncode(header)), partialName, model, viewData, options, id);
        }
        public MvcHtmlString AccordionGroupFromPartial(IHtmlString header, string partialName, object model = null, ViewDataDictionary viewData = null, AccordionGroupOptions options = AccordionGroupOptions.None, string id = null)
        {
            if (String.IsNullOrWhiteSpace(id))
                id = System.Guid.NewGuid().ToString("N");

            string s = "<div class=\"accordion-group\">\r\n";
            s += "<div class=\"accordion-heading\">\r\n";
            s += "<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#" + this.Accordion.Id + "\" href=\"#" + id + "\">\r\n";
            s += header.ToHtmlString();
            s += "</a>\r\n";
            s += "</div>\r\n";
            s += "<div id=\"" + id + "\" class=\"accordion-body collapse";

            if ((options & AccordionGroupOptions.In) == AccordionGroupOptions.In)
                s += " in";

            s += "\">\r\n";
            s += "<div class=\"accordion-inner\">\r\n";

            s += _htmlHelper.Partial(partialName, model, viewData).ToHtmlString();

            s += "</div></div></div>\r\n";

            return new MvcHtmlString(s);
        }
    }

    public class Accordion
    {
        public string Id { get; set; }
        public RouteValueDictionary HtmlAttributes { get; set; }

        public Accordion(string id, RouteValueDictionary htmlAttributes)
        {
            if (String.IsNullOrWhiteSpace(id))
                Id = System.Guid.NewGuid().ToString("N");
            else
                Id = id;

            HtmlAttributes = htmlAttributes;
        }

        public AccordionGroup CreateAccordionGroup(AccordionGroupOptions options = AccordionGroupOptions.None, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            return new AccordionGroup(this, options, id, attrs);
        }
    }

    public class AccordionGroupSection : BstSection
    {
        private Accordion _accordion;
        public AccordionGroup AccordionGroup { get; set; }

        public AccordionGroupSection(Accordion accordion, ViewContext viewContext, AccordionGroup accordionGroup, AccordionGroupOptions options, string id, RouteValueDictionary htmlAttributes)
            : base(viewContext, "</div></div></div>\r\n")
        {
            if (accordion == null)
                throw (new ArgumentNullException());

            _accordion = accordion;

            if (accordionGroup != null)
                AccordionGroup = accordionGroup;
            else
                AccordionGroup = new AccordionGroup(accordion, options, id, htmlAttributes);
        }

        public string StartHtml(IHtmlString header)
        {
            string s = "<div class=\"accordion-group\">\r\n";
            s += "<div class=\"accordion-heading\">\r\n";
            s += "<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#"  + _accordion.Id + "\" href=\"#"  + AccordionGroup.Id + "\">\r\n";
            s += header.ToHtmlString();
            s += "</a>\r\n";
            s += "</div>\r\n";
            s += "<div id=\"" + AccordionGroup.Id + "\" class=\"accordion-body collapse";

            if ((AccordionGroup.Options & AccordionGroupOptions.In) == AccordionGroupOptions.In)
                s += " in";

            s += "\">\r\n";
            s += "<div class=\"accordion-inner\">\r\n";

            return s;
        }
    }

    [FlagsAttribute]
    public enum AccordionGroupOptions
    { 
        None,
        In
    }

    public class AccordionGroup
    {
        private readonly Accordion _accordion;
        public string Id { get; set; }
        public AccordionGroupOptions Options { get; set; }
        public RouteValueDictionary HtmlAttributes { get; set; }

        public AccordionGroup(Accordion accordion, AccordionGroupOptions options, string id, RouteValueDictionary htmlAttributes)
        {
            _accordion = accordion;
            Options = options;
            HtmlAttributes = htmlAttributes;

            if (String.IsNullOrWhiteSpace(id))
                Id = System.Guid.NewGuid().ToString("N");
            else
                Id = id;
        }

        public MvcHtmlString ToggleJS(string action = "toggle")
        {
            string s = "$('#" + Id + "').collapse('" + action + "');";            
            return new MvcHtmlString(s);
        }

        public MvcHtmlString ToggleAttr()
        {
            string s = "data-toggle=\"collapse\" data-target=\"#" + Id + "\" ";

            return new MvcHtmlString(s);
        }
    }
}
